use std::thread;

use crate::{serve, utils::UninitMutCell};
use log::{error, info};
use tokio::{runtime::Runtime, sync::Semaphore};

pub struct AppInfo {
    pub exit_sem: Semaphore,
}

pub static APP_INFO: UninitMutCell<AppInfo> = UninitMutCell::const_new();

async fn run_main(path: String) {
    info!("db path with:{}", path);

    tokio::select! {
        _ = APP_INFO.exit_sem.acquire() => {
            info!("native serve exit");
        },

        ret = serve::run(&path) => {
            if let Err(e) = ret {
                error!("err:{}", e);
            }
        }
    }
}

impl AppInfo {
    pub fn init_once(path: String) {
        unsafe {
            APP_INFO.write(AppInfo {
                exit_sem: Semaphore::new(0),
            });
        }
        thread::spawn(move || {
            Runtime::new().unwrap().block_on(run_main(path));
        });
    }
}

pub fn shutdown() {
    APP_INFO.exit_sem.add_permits(1);
}
